//
//  NetworkTools.swift
//  HMWeibo08
//
//  Created by 唐万超 on 15/7/30.
//  Copyright © 2015年 唐万超. All rights reserved.
//

import UIKit
import AFNetworking

/// 错误类别标记
private let HMErrorDomainName = "com.itheima.error.network"

/// 枚举定义错误，可以有属性有方法
private enum HMNetworkError: Int {

    case emptyDataError = -1
    case emptyTokenError = -2
    
    /// 属性，错误描述
    private var errorDescription: String {
    
        switch self {
        case .emptyDataError: return "空数据错误"
        case .emptyTokenError: return " Token  为空"
        }
        
    }
    
    /// 根据枚举类型，返回对应的错误
    private func error() -> NSError {
    
        return NSError(domain: HMErrorDomainName, code: rawValue, userInfo: [HMErrorDomainName : errorDescription])
    }

}

/// 定义网络请求的方法
private enum HMNetWorkMethod: String {

    case GET = "GET"
    case POST = "POST"
}

class NetworkTools: AFHTTPSessionManager {
    
    // MARK: - 应用程序信息
    
    /// 申请应用时分配的AppKey。
    private let clientId = "2158449023"
    /// App Secret
    private let appSecret = "5ca40adf66790a27e4d7aa2a72808298"
    /// 授权回调地址，站外应用需与设置的回调地址一致，站内应用需填写canvas page的地址。
    let redirectUri = "http://www.baidu.com"
    
    /// 网络回调类型别名
    typealias HMNetFinishedCallBack = (result: [String : AnyObject]?, error: NSError?) -> ()
    
    // 单例方法，全局的访问点
    static let sharedNetworkTools:NetworkTools = {
        
        //   https://api.weibo.com/oauth2/authorize
        let url = NSURL(string: "https://api.weibo.com/")!
        
        let tools = NetworkTools(baseURL: url)
        // self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];
        tools.responseSerializer.acceptableContentTypes = NSSet(objects: "application/json", "text/json", "text/javascript", "text/plain") as Set<NSObject>
        
        return tools
        
    }()
    
    /// 检查并生成token字典参数
    private func tokenDict (finished:HMNetFinishedCallBack) -> [String : AnyObject]? {
    
        // 判断token是否存在
        if UserAccount.loadAccount()?.access_token == nil {
            
            // 判断此处错误类型并打印
            let error = HMNetworkError.emptyTokenError.error()
            print(error)
            
            finished(result: nil, error: error)
            
            return nil
            
        }
        
        return ["access_token" : UserAccount.loadAccount()!.access_token!]

    }
    
    /**
    since_id    则返回ID比since_id大的微博（即比since_id时间晚的微博），默认为0
    max_id      则返回ID`小于或等于max_id`的微博，默认为0
    */
    // MARK: - 加载微博数据
    func loadStatus(since_id: Int, max_id: Int, finished:HMNetFinishedCallBack) {
    
//        // 判断token是否存在
//        if UserAccount.loadAccount()?.access_token == nil {
//        
//            // 判断此处错误类型并打印
//            let error = HMNetworkError.emptyTokenError.error()
//            print(error)
//            
//            finished(result: nil, error: error)
//            return
//            
//        }
        
        guard var params = tokenDict(finished) else {
        
            return
        }
        
        if since_id > 0 {
            params["since_id"] = since_id
        }
        
        if max_id > 0 {
            params["max_id"] = max_id - 1
        }
        
        let urlString = "2/statuses/home_timeline.json"
//        let params: [String : AnyObject] = ["access_token" : UserAccount.loadAccount()!.access_token!]
        
        request(HMNetWorkMethod.GET, urlString: urlString, params: params, finished: finished)
        
    }
    
    // MARK: - 加载用户数据
    /// uid   用户代号字符串
    /// finished    完成回调
    func loadUserInfo (uid: String, finished: HMNetFinishedCallBack) {
    
//        // 判断token是否存在
//        if UserAccount.loadAccount()?.access_token == nil {
//        
//            // 此处判断错误类型并打印
//            let error = HMNetworkError.emptyTokenError.error()
//            
//            print(error)
//            
//            finished(result: nil, error: error)
//            return
//            
//        }
        guard var params = tokenDict(finished) else {
            
            return
        }
        
        let urlString = "2/users/show.json"
//        let params : [String: AnyObject] = ["access_token" : UserAccount.loadAccount()!.access_token!, "uid" : uid]
        params["uid"] = uid
        
        // 发送网络请求 , 此时不需要进行回调，因此直接finished
       // requestGET(urlString, params: params, finished: finished)
        request(HMNetWorkMethod.GET, urlString: urlString, params: params, finished: finished)
        
    }
   
    
    func oauthUrl() -> NSURL {
    
        let urlStr = "https://api.weibo.com/oauth2/authorize?client_id=\(clientId)&redirect_uri=\(redirectUri)"
        
        return NSURL(string: urlStr)!
        
    }
    
   
    
    /// 获取accessToken   (重构，闭包参数进行回调，一个闭包两个参数，无返回值)
    func loadAccessToken(code: String, finished: HMNetFinishedCallBack) {
    
        let urlString = "https://api.weibo.com/oauth2/access_token"
        
        let params = ["client_id" : clientId,
        
            "client_secret" : appSecret,
            "grant_type" : "authorization_code",
            "code" : code,
            "redirect_uri" : redirectUri
        ]
        
        request(HMNetWorkMethod.POST, urlString: urlString, params: params, finished: finished)
        
    
    }
    
    
    // MARK: - 封装AFN网络方法，便于替换网络访问方法，第三方框架的网络代码全部集中在此
    private func request(method: HMNetWorkMethod, urlString: String, params: [String : AnyObject], finished:HMNetFinishedCallBack) {
    
        let succeedCallBack:(NSURLSessionDataTask!, AnyObject!) -> Void = { (_, JSON) -> Void in
            
            if let result = JSON as? [String : AnyObject] {
                // 获得数据
                finished(result: result, error: nil)
                
            }else {
                // 没有获得数据，但是也没有明显网络错误
                print("没有数据 GET Request \(urlString)")
                
                /**
                自定义错误
                domain: 错误的范围/大类别，定义一个常量字符串
                code: 错误代号，有些公司会专门定义一个特别大的.h，定义所有的错误编码，通常是负数
                userInfo: 可以传递一些附加的错误信息
                */
                
                //let error = NSError(domain: HMErrorDomainName, code: -1, userInfo: ["errorMessage" : "空数据"])
                
                finished(result: nil, error: HMNetworkError.emptyDataError.error())
                
            }
            
        }
        
        let failedCallBack:(NSURLSessionDataTask!, NSError!) -> Void =  { (_, error) -> Void in
            
            print(error)
            
            finished(result: nil, error: error)
            
        }
        
        switch method {
        case .GET:
            GET(urlString, parameters: params, success: succeedCallBack, failure: failedCallBack)
        case .POST:
            POST(urlString, parameters: params, success: succeedCallBack, failure: failedCallBack)
        }
        
    }
    
   
}
